package impl;

import anaydis.sort.SorterType;
import com.sun.istack.internal.NotNull;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class ShellSorter extends AbstractSorter {

    public ShellSorter(){
        super(SorterType.SHELL);        
    }

    public <T> void sort(@NotNull Comparator<T> tComparator, @NotNull List<T> ts) {
        HSorter hsort = new HSorter();
        int h = 1;
        while ((h*3+1) <= ts.size()){
            h = h * 3 + 1;} // (1, 4, 13, 40, 121, ...)

        while (h > 0){ // voy a achicar h hasta h=1
            hsort.sort(tComparator, ts, h); // h-sort el array
            h = (h - 1) / 3; // achico h
        }
    }

    public <T> void sort(@NotNull Comparator<T> tComparator, @NotNull List<T> ts, ArrayList<Integer> intList) {
        int h;
        HSorter hsort = new HSorter();
        int j = intList.size();

        //while ((h*3+1) <= ts.size()){
            //h = h * 3 + 1;} // (1, 4, 13, 40, 121, ...)

        do{ // voy a achicar h hasta h=1
            h = intList.get(j-1);
            hsort.sort(tComparator, ts, h); // h-sort el array
            j--;
        }while (h > 0);
    }

    public ArrayList<Integer> secuenciaUno(int n){
        ArrayList intList = new ArrayList<Integer>();
        for(int i=1; (i*3+1) <= n; i=i*3+1){
            intList.add(i);
        }
        return intList;
    }

    public ArrayList<Integer> secuenciaDos(int n){
        ArrayList intList = new ArrayList<Integer>();
        for(int i=1; ((4^(i+1))+3*(2^(i))+1) <= n; i=i*3+1){
            intList.add(i);
        }
        return intList;
    }
}